package com.nanhai.buddhist.college.module.collegebase.service.textbookinfo.type;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil;
import com.nanhai.buddhist.college.framework.common.pojo.PageResult;
import com.nanhai.buddhist.college.framework.common.util.collection.CollectionUtils;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.textbookinfo.type.vo.TextbookTypeCreateReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.textbookinfo.type.vo.TextbookTypeExportReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.textbookinfo.type.vo.TextbookTypePageReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.textbookinfo.type.vo.TextbookTypeTreeRespVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.textbookinfo.type.vo.TextbookTypeTreeRespVO1;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.textbookinfo.type.vo.TextbookTypeUpdateReqVO;
import com.nanhai.buddhist.college.module.collegebase.convert.textbookinfo.type.TextbookTypeConvert;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.textbooktype.TextbookTypeDO;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.textbookinfo.TextbookTypeMapper;
import com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 教材分类 Service 实现类
 *
 * @author AKai
 */
@Service
@Validated
public class TextbookTypeServiceImpl implements TextbookTypeService {

    @Resource
    private TextbookTypeMapper textbookTypeMapper;

    @Override
    public String createTextbookType(TextbookTypeCreateReqVO createReqVO) {
        // 插入
        TextbookTypeDO textbookType = TextbookTypeConvert.INSTANCE.convert(createReqVO);
        textbookTypeMapper.insert(textbookType);
        // 返回
        return textbookType.getId();
    }

    @Override
    public void updateTextbookType(TextbookTypeUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateTextbookTypeExists(updateReqVO.getId());

        if (updateReqVO.getId().equals(updateReqVO.getParentId())) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TEXTBOOK_TYPE_ID_EQ_PARENT);
        }
        // 更新
        TextbookTypeDO updateObj = TextbookTypeConvert.INSTANCE.convert(updateReqVO);
        textbookTypeMapper.updateById(updateObj);
    }

    @Override
    public void deleteTextbookType(String id) {
        // 校验存在
        this.validateTextbookTypeExists(id);
        // 递归获取子集
        int i = 10;
        List<String> ids = new ArrayList<>();
        ids.add(id);
        List<TextbookTypeDO> textbookTypeDOS = textbookTypeMapper.selectList(new LambdaUpdateWrapper<TextbookTypeDO>().eq(TextbookTypeDO::getParentId, id));
        // 递归获取子类id
        getSunId(ids, textbookTypeDOS, i);

        // 删除
        textbookTypeMapper.deleteBatchIds(ids);
    }

    private void getSunId(List<String> ids, List<TextbookTypeDO> textbookTypeDOS, int i) {
        if (CollectionUtil.isEmpty(textbookTypeDOS)) {
            return;
        }
        List<String> collect = textbookTypeDOS.stream().map(TextbookTypeDO::getId).collect(Collectors.toList());
        List<TextbookTypeDO> textbookTypeDOS1 = textbookTypeMapper.selectList(new LambdaUpdateWrapper<TextbookTypeDO>().in(TextbookTypeDO::getParentId, collect));
        // 是否有相同数据  防止脏数据引起死锁  类如父类id 和 自身id相同
        List<String> intersection = ids.stream().filter(collect::contains).collect(Collectors.toList());

        ids.addAll(collect);
        if (CollectionUtil.isEmpty(textbookTypeDOS1) || i == 0 || !intersection.isEmpty()) {
            return;
        }
        --i;
        getSunId(ids, textbookTypeDOS1, i);


    }

    private void validateTextbookTypeExists(String id) {
        if (textbookTypeMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TEXTBOOK_TYPE_NOT_EXISTS);
        }
    }

    @Override
    public TextbookTypeDO getTextbookType(String id) {
        TextbookTypeDO textbookTypeDO = textbookTypeMapper.selectById(id);
        List<String> parentIds = new ArrayList<>();
        // 10级  递归保险
        Integer i = 10;
        // 递归获取父级id
        getParentIds(textbookTypeDO, parentIds, i);
        textbookTypeDO.setParentIds(parentIds);
        return textbookTypeDO;
    }

    @NotNull
    private void getParentIds(TextbookTypeDO textbookTypeDO, List<String> parentIds, Integer i) {
        if (ObjectUtil.isNotNull(textbookTypeDO) && !"0".equals(textbookTypeDO.getParentId())) {
            parentIds.add(textbookTypeDO.getParentId());
            TextbookTypeDO textbookTypeDO1 = textbookTypeMapper.selectById(textbookTypeDO.getParentId());
            int size = parentIds.stream().filter(s -> s.equals(textbookTypeDO1.getParentId())).collect(Collectors.toList()).size();
            if (ObjectUtil.isNull(textbookTypeDO) || i == 0 || size > 0) {
                return;
            }
            --i;
            getParentIds(textbookTypeDO1, parentIds, i);
        }
    }

    @Override
    public List<TextbookTypeDO> getTextbookTypeList(Collection<String> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : textbookTypeMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<TextbookTypeDO> getTextbookTypePage(TextbookTypePageReqVO pageReqVO) {
        return textbookTypeMapper.selectPage(pageReqVO);
    }

    @Override
    public List<TextbookTypeDO> getTextbookTypeList(TextbookTypeExportReqVO exportReqVO) {
        return textbookTypeMapper.selectList(exportReqVO);
    }

    @Override
    public List<TextbookTypeTreeRespVO1> getTextbookTypeTreeList() {
        List<TextbookTypeTreeRespVO1> resList = new ArrayList<>();
        List<TextbookTypeDO> textbookTypeDOS = textbookTypeMapper.selectList(new LambdaUpdateWrapper<>());
        if (CollectionUtil.isEmpty(textbookTypeDOS)) {
            return resList;
        }
        List<TextbookTypeDO> collect = textbookTypeDOS.stream().filter(s -> "0".equals(s.getParentId())).collect(Collectors.toList());
        resList = getTextbookTypeTreeRespVOS(textbookTypeDOS, collect);

        return resList;
    }

    @Override
    public PageResult<TextbookTypeTreeRespVO> getTextbookTypeTreePage(TextbookTypePageReqVO pageVO) {
        PageResult<TextbookTypeDO> selectPage = textbookTypeMapper.selectTreePage(pageVO);
        PageResult<TextbookTypeTreeRespVO> resPage = new PageResult<>();
        resPage.setTotal(selectPage.getTotal());
        if (CollectionUtil.isEmpty(selectPage.getList())) {
            return resPage;
        }
        List<TextbookTypeTreeRespVO> resList = getTextbookTypeTreePageRespVOS(selectPage.getList());
        resPage.setList(resList);
        return resPage;
    }

    /***
     * 查询所有数状结构
     * @param textbookTypeDOS
     * @param collect
     * @return
     */
    @NotNull
    private List<TextbookTypeTreeRespVO1> getTextbookTypeTreeRespVOS(List<TextbookTypeDO> textbookTypeDOS, List<TextbookTypeDO> collect) {
        List<TextbookTypeTreeRespVO1> resList = new ArrayList<>(collect.size());
        for (TextbookTypeDO textbookTypeDO : collect) {
            TextbookTypeTreeRespVO1 respVO = new TextbookTypeTreeRespVO1();
            BeanUtils.copyProperties(textbookTypeDO, respVO);
            List<TextbookTypeDO> collect1 = textbookTypeDOS.stream().filter(s -> textbookTypeDO.getId().equals(s.getParentId())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect1)) {
                respVO.setSonList(getTextbookTypeTreeRespVOS(textbookTypeDOS, collect1));
            }
            resList.add(respVO);
        }
        return resList;
    }

    /**
     * 分页查询树状结构
     *
     * @param collect
     * @return
     */
    @NotNull
    private List<TextbookTypeTreeRespVO> getTextbookTypeTreePageRespVOS(List<TextbookTypeDO> collect) {
        List<TextbookTypeTreeRespVO> resList = new ArrayList<>(collect.size());
        for (TextbookTypeDO textbookTypeDO : collect) {
            TextbookTypeTreeRespVO respVO = new TextbookTypeTreeRespVO();
            BeanUtils.copyProperties(textbookTypeDO, respVO);
            List<TextbookTypeDO> collect1 = textbookTypeMapper.selectList(new LambdaUpdateWrapper<TextbookTypeDO>().eq(TextbookTypeDO::getParentId, textbookTypeDO.getId()));
            if (CollectionUtil.isNotEmpty(collect1)) {
                respVO.setChildren(getTextbookTypeTreePageRespVOS(collect1));
            }
            resList.add(respVO);
        }
        return resList;
    }

}
